#include "Resources.h"

#include <cassert>

using namespace std;

Resources* Resources::instance = NULL;

Resources::Resources(void)
{
    ofSetDataPathRoot("data/");

    textures[TERRAIN] = SOIL_load_OGL_texture(
        "data/terrain.png",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_MULTIPLY_ALPHA);
    glBindTexture(GL_TEXTURE_2D, textures[TERRAIN]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    textures[DIAMONDPICKAXE] = SOIL_load_OGL_texture(
        "data/diamondpickaxe.png",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_MULTIPLY_ALPHA |
        SOIL_FLAG_INVERT_Y);
    glBindTexture(GL_TEXTURE_2D, textures[DIAMONDPICKAXE]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    textures[DIAMONDSHOVEL] = SOIL_load_OGL_texture(
        "data/diamondshovel.png",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_MULTIPLY_ALPHA |
        SOIL_FLAG_INVERT_Y);
    glBindTexture(GL_TEXTURE_2D, textures[DIAMONDSHOVEL]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    textures[BACKGROUND] = SOIL_load_OGL_texture(
        "data/bg.png",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        NULL);

    lists[SQUARE1X1] = glGenLists(1);
    glNewList(lists[SQUARE1X1], GL_COMPILE);
        glBegin(GL_QUADS);
            glTexCoord2i(0, 0);
                glVertex2i(0, 0);
            glTexCoord2i(1, 0);
                glVertex2i(1, 0);
            glTexCoord2i(1, 1);
                glVertex2i(1, 1);
            glTexCoord2i(0, 1);
                glVertex2i(0, 1);
        glEnd();
    glEndList();

    const float s = 1.0f/16.0f;
    for (int i = 0; i < 16*16; ++i) {
        float y = (i/16)*s;
        float x = (i%16)*s;

        lists[TERRAINBEGIN+i] = glGenLists(1);
        glNewList(lists[TERRAINBEGIN+i], GL_COMPILE);
            glBindTexture(GL_TEXTURE_2D, textures[TERRAIN]);
            glBegin(GL_QUADS);
                glTexCoord2f(x, y+s);
                    glVertex2i(0, 0);
                glTexCoord2f(x+s, y+s);
                    glVertex2i(1, 0);
                glTexCoord2f(x+s, y);
                    glVertex2i(1, 1);
                glTexCoord2f(x, y);
                    glVertex2i(0, 1);
            glEnd();
        glEndList();
    }
}

Resources* Resources::get() {
    if (!instance)
        instance = new Resources;

    return instance;
}

GLint Resources::textureByID(int ID) {
    return textures[ID];
}

GLint Resources::list(int listID) {
    return lists[listID];
}

GLint Resources::listByID(int ID) {
    if (ID == -1) return -1;
    return terrainListByID(ID);
}

GLint Resources::terrainListByID(int ID) {
    int id;

    switch (ID) { // 14 is undefined.
        case 1:  id = 1;  break;
        case 2:  id = 3;  break;
        case 3:  id = 2;  break;
        case 4:  id = 16; break;
        case 5:  id = 4;  break;
        case 6:  id = 15; break;
        case 7:  id = 17; break;
        case 12: id = 18; break;
        case 13: id = 19; break;
        case 14: id = 32; break;
        case 15: id = 33; break;
        case 16: id = 34; break;
        case 17: id = 20; break;
        case 18: id = 52; break;
        case 20: id = 49; break;
        case 37: id = 13; break;
        case 38: id = 12; break;
        case 39: id = 29; break;
        case 40: id = 28; break;
        default: id = 14; break;
    }

    id += TERRAINBEGIN;
    return lists[id];
}

GLint Resources::backgroundTexture() {
    return textures[BACKGROUND];
}

void Resources::release() {
    delete instance;
}
